home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / samples / nurb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-15  |  6.4 KB  |  354 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include <GL/glut.h>
  30.  
  31.  
  32. #define INREAL float
  33.  
  34. #define S_NUMPOINTS 13
  35. #define S_ORDER     3   
  36. #define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
  37. #define T_NUMPOINTS 3
  38. #define T_ORDER     3 
  39. #define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
  40. #define SQRT_TWO    1.41421356237309504880
  41.  
  42.  
  43. typedef INREAL Point[4];
  44.  
  45.  
  46. GLenum doubleBuffer;
  47.  
  48. GLenum expectedError;
  49. GLint rotX = 40, rotY = 40;
  50. INREAL sknots[S_NUMKNOTS] = {
  51.     -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
  52.     4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0, 9.0
  53. };
  54. INREAL tknots[T_NUMKNOTS] = {
  55.     1.0, 1.0, 1.0, 2.0, 2.0, 2.0
  56. };
  57. Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] = {
  58.     {
  59.     {
  60.         4.0, 2.0, 2.0, 1.0
  61.     },
  62.     {
  63.         4.0, 1.6, 2.5, 1.0
  64.     },
  65.     {
  66.         4.0, 2.0, 3.0, 1.0
  67.     }
  68.     },
  69.     {
  70.     {
  71.         5.0, 4.0, 2.0, 1.0
  72.     },
  73.     {
  74.         5.0, 4.0, 2.5, 1.0
  75.     },
  76.     {
  77.         5.0, 4.0, 3.0, 1.0
  78.     }
  79.     },
  80.     {
  81.     {
  82.         6.0, 5.0, 2.0, 1.0
  83.     },
  84.     {
  85.         6.0, 5.0, 2.5, 1.0
  86.     },
  87.     {
  88.         6.0, 5.0, 3.0, 1.0
  89.     }
  90.     },
  91.     {
  92.     {
  93.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  94.     },
  95.     {
  96.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  97.     },
  98.     {
  99.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  100.     }  
  101.     },
  102.     {
  103.     {
  104.         5.2, 6.7, 2.0, 1.0
  105.     },
  106.     {
  107.         5.2, 6.7, 2.5, 1.0
  108.     },
  109.     {
  110.         5.2, 6.7, 3.0, 1.0
  111.     }
  112.     },
  113.     {
  114.     {
  115.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  116.     },
  117.     {
  118.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  119.     }, 
  120.     {
  121.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  122.     }  
  123.     }, 
  124.     {
  125.     {
  126.         4.0, 5.2, 2.0, 1.0
  127.     },
  128.     {
  129.         4.0, 4.6, 2.5, 1.0
  130.     },
  131.     {
  132.         4.0, 5.2, 3.0, 1.0
  133.     }  
  134.     },
  135.     {
  136.     {
  137.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  138.     },
  139.     {
  140.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  141.     },
  142.     {
  143.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  144.     }  
  145.     },
  146.     {
  147.     {
  148.         2.8, 6.7, 2.0, 1.0
  149.     },
  150.     {
  151.         2.8, 6.7, 2.5, 1.0
  152.     },
  153.     {
  154.         2.8, 6.7, 3.0, 1.0
  155.     }   
  156.     },
  157.     {
  158.     {
  159.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  160.     },
  161.     {
  162.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  163.     },
  164.     {
  165.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  166.     }  
  167.     },
  168.     {
  169.     {
  170.         2.0, 5.0, 2.0, 1.0
  171.     },
  172.     {
  173.         2.0, 5.0, 2.5, 1.0
  174.     },
  175.     {
  176.         2.0, 5.0, 3.0, 1.0
  177.     } 
  178.     },
  179.     {
  180.     {
  181.         3.0, 4.0, 2.0, 1.0
  182.     },
  183.     {
  184.         3.0, 4.0, 2.5, 1.0
  185.     },
  186.     {
  187.         3.0, 4.0, 3.0, 1.0
  188.     } 
  189.     },
  190.     {
  191.     {
  192.         4.0, 2.0, 2.0, 1.0
  193.     },
  194.     {
  195.         4.0, 1.6, 2.5, 1.0
  196.     },
  197.     {
  198.         4.0, 2.0, 3.0, 1.0
  199.     }    
  200.     }
  201. };
  202. GLUnurbsObj *theNurbs;
  203.  
  204.  
  205. static void CALLBACK ErrorCallback(GLenum which)
  206. {
  207.  
  208.     if (which != expectedError) {
  209.     fprintf(stderr, "Unexpected error occured (%d):\n", which);
  210.     fprintf(stderr, "    %s\n", (char *) gluErrorString(which));
  211.     }
  212. }
  213.  
  214. static void Init(void)
  215. {
  216.  
  217.     theNurbs = gluNewNurbsRenderer();
  218. #ifndef __STORM__
  219.     gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
  220. #else
  221.     gluNurbsCallback(theNurbs, GLU_ERROR, (void(CALLBACK *)())ErrorCallback);
  222. #endif
  223.  
  224.     gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
  225.     gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
  226.  
  227.     expectedError = GLU_INVALID_ENUM;
  228.     gluNurbsProperty(theNurbs, ~0, 15.0);
  229.     expectedError = GLU_NURBS_ERROR13;
  230.     gluEndSurface(theNurbs);
  231.     expectedError = 0;
  232.  
  233.     glColor3f(1.0, 1.0, 1.0);
  234. }
  235.  
  236. static void Reshape(int width, int height)
  237. {
  238.  
  239.     glViewport(0, 0, (GLint)width, (GLint)height);
  240.  
  241.     glMatrixMode(GL_PROJECTION);
  242.     glLoadIdentity();
  243.     glFrustum(-2.0, 2.0, -2.0, 2.0, 0.8, 10.0);
  244.     gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.5, 6.0, -3.0, 2.0);
  245.     glMatrixMode(GL_MODELVIEW);
  246. }
  247.  
  248. static void Key2(int key, int x, int y)
  249. {
  250.  
  251.     switch (key) {
  252.       case GLUT_KEY_DOWN:
  253.     rotX -= 5;
  254.     break;
  255.       case GLUT_KEY_UP:
  256.     rotX += 5;
  257.     break;
  258.       case GLUT_KEY_LEFT:
  259.     rotY -= 5;
  260.     break;
  261.       case GLUT_KEY_RIGHT:
  262.     rotY += 5;
  263.     break;
  264.       default:
  265.     return;
  266.     }
  267.  
  268.     glutPostRedisplay();
  269. }
  270.  
  271. static void Key(unsigned char key, int x, int y)
  272. {
  273.  
  274.     switch (key) {
  275.       case 27:
  276.     exit(1);
  277.     }
  278. }
  279.  
  280. static void Draw(void)
  281. {
  282.  
  283.     glClear(GL_COLOR_BUFFER_BIT);
  284.  
  285.     glPushMatrix();
  286.  
  287.     glTranslatef(4.0, 4.5, 2.5);
  288.     glRotatef(rotY, 1, 0, 0);
  289.     glRotatef(rotX, 0, 1, 0);
  290.     glTranslatef(-4.0, -4.5, -2.5);
  291.  
  292.     gluBeginSurface(theNurbs);
  293.     gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
  294.             4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
  295.             T_ORDER, GL_MAP2_VERTEX_4);
  296.     gluEndSurface(theNurbs);
  297.  
  298.     glPopMatrix();
  299.  
  300.     glFlush();
  301.  
  302.     if (doubleBuffer) {
  303.     glutSwapBuffers();
  304.     }
  305. }
  306.  
  307. static GLenum Args(int argc, char **argv)
  308. {
  309.     GLint i;
  310.  
  311.     doubleBuffer = GL_FALSE;
  312.  
  313.     for (i = 1; i < argc; i++) {
  314.     if (strcmp(argv[i], "-sb") == 0) {
  315.         doubleBuffer = GL_FALSE;
  316.     } else if (strcmp(argv[i], "-db") == 0) {
  317.         doubleBuffer = GL_TRUE;
  318.     } else {
  319.         printf("%s (Bad option).\n", argv[i]);
  320.         return GL_FALSE;
  321.     }
  322.     }
  323.     return GL_TRUE;
  324. }
  325.  
  326. void main(int argc, char **argv)
  327. {
  328.     GLenum type;
  329.  
  330.     glutInit(&argc, argv);
  331.  
  332.     if (Args(argc, argv) == GL_FALSE) {
  333.     exit(1);
  334.     }
  335.  
  336.     glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
  337.  
  338.     type = GLUT_RGB;
  339.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  340.     glutInitDisplayMode(type);
  341.  
  342.     if (glutCreateWindow("NURBS Test") == GL_FALSE) {
  343.     exit(1);
  344.     }
  345.  
  346.     Init();
  347.  
  348.     glutReshapeFunc(Reshape);
  349.     glutKeyboardFunc(Key);
  350.     glutSpecialFunc(Key2);
  351.     glutDisplayFunc(Draw);
  352.     glutMainLoop();
  353. }
  354.